/**
 * Copyright &copy; 2015-2020 <a href="http://www.jeeplus.org/">JeePlus</a> All rights reserved.
 */
package com.z100h.supplychain.purchase.service;

import java.text.SimpleDateFormat;

import java.util.Date;
import java.util.List;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.jeeplus.core.facade.FacadeException;
import com.jeeplus.core.persistence.Page;
import com.jeeplus.core.service.CrudService;
import com.jeeplus.modules.sys.entity.User;
import com.jeeplus.modules.sys.utils.UserUtils;
import com.z100h.supplychain.core.EvidenceLockState;
import com.z100h.supplychain.core.EvidenceType;
import com.z100h.supplychain.core.ScEventServiceType;
import com.z100h.supplychain.core.ScEventType;
import com.z100h.supplychain.evidence.entity.ScEvent;
import com.z100h.supplychain.evidence.entity.WarehouseReceipt;
import com.z100h.supplychain.evidence.facade.WarehousingFacade;
import com.z100h.supplychain.evidence.mapper.ScEventMapper;
import com.z100h.supplychain.purchase.entity.PurchaseOrder;
import com.z100h.supplychain.purchase.entity.PurchaseOrderItem;
import com.z100h.supplychain.purchase.entity.PurchaseOrderItemErpInfo;
import com.z100h.supplychain.purchase.entity.PurchaseOrderItemVo;
import com.z100h.supplychain.purchase.mapper.PurchaseOrderMapper;

/**
 * 供应链采购单Service
 *
 * @author madara
 * @version 2018-09-20
 */
@Service
@Transactional(readOnly = true)
public class PurchaseOrderService extends CrudService<PurchaseOrderMapper, PurchaseOrder> {

	private static final Logger logger = LoggerFactory.getLogger(PurchaseOrderService.class);

	@Autowired
	private PurchaseOrderMapper purchaseOrderMapper;

	@Autowired
	private PurchaseOrderItemService purchaseOrderItemService;

	@Autowired
	private WarehousingFacade<WarehouseReceipt> warehousingFacade;

	@Autowired
	private ScEventMapper scEventMapper;

	// @Autowired
	// private MySingleExecutor mySingleExecutor;

	@Override
	public PurchaseOrder get(String id) {
		return super.get(id);
	}

	@Override
	public List<PurchaseOrder> findList(PurchaseOrder purchaseOrder) {
		return super.findList(purchaseOrder);
	}

	@Override
	public Page<PurchaseOrder> findPage(Page<PurchaseOrder> page, PurchaseOrder purchaseOrder) {
		return super.findPage(page, purchaseOrder);
	}

	@Override
	@Transactional(readOnly = false)
	public void save(PurchaseOrder purchaseOrder) {
		super.save(purchaseOrder);
	}

	@Override
	@Transactional(readOnly = false)
	public void delete(PurchaseOrder purchaseOrder) {
		super.delete(purchaseOrder);
	}

	/**
	 * 采购单入库检查
	 * 检查重复条件：七天内，供应商，总钱，总数，标准采购单
	 * 满足重复条件提示："该采购单疑似重复录入，请选择处理方式！"
	 * 
	 * @param purchaseOrderId
	 * @author: FYH - 1009173473@qq.com
	 * @date: Created on 2022年7月19日 下午4:37:40
	 */
	private void checkWarehouseReceiptRepetition(String purchaseOrderId) {

		Integer count = purchaseOrderMapper.checkWarehouseReceiptRepetition(purchaseOrderId);

		if (count.compareTo(0) > 0) {
			throw new FacadeException("该采购单疑似重复录入，请选择处理方式！");

		}
	}

	@Transactional(readOnly = false)
	public String createWarehouseReceipt(String purchaseOrderId, Boolean ignore) {
		String evidenceId = null;

		/**
		 * 是否存在采购详情sku
		 */
		List<PurchaseOrderItemVo> list = purchaseOrderItemService.findPurchaseOrderItemList(purchaseOrderId);
		if (CollectionUtils.isEmpty(list)) {
			throw new FacadeException("采购sku为空!");
		}

		List<String> ids = purchaseOrderMapper.findNullPurchaseOrderDetail(purchaseOrderId);
		if (CollectionUtils.isNotEmpty(ids)) {
			throw new FacadeException("请检查单价或者数量!");
		}

		if (ignore == null || !ignore) {
			checkWarehouseReceiptRepetition(purchaseOrderId);
		}

		/**
		 * 创建入库单
		 */
		WarehouseReceipt warehouseReceipt = new WarehouseReceipt();
		warehouseReceipt.setReceiptType(EvidenceType.PURCHASERECEIPT.getType());
		try {
			evidenceId = warehousingFacade.createWarehouseReceipt(warehouseReceipt);
		} catch (Throwable e1) {
			e1.printStackTrace();
		}

		/**
		 * 更新采购单
		 */
		PurchaseOrder purchaseOrder = this.get(purchaseOrderId);
		// 完成
		purchaseOrder.setState(EvidenceLockState.LOCK.getValue());
		purchaseOrder.setEvidenceId(evidenceId);
		purchaseOrder.setFinishTime(new Date());
		this.save(purchaseOrder);

		// 保存采购完成动作
		ScEvent scEvent1 = new ScEvent(purchaseOrderId, ScEventServiceType.PURCHASEORDER.getType(),
				ScEventType.FINISHPURCHASEORDER.getType(), UserUtils.getUser().getId());
		scEventMapper.insertScEvent(scEvent1);

		// 保存入库创建动作
		ScEvent scEvent2 = new ScEvent(evidenceId, ScEventServiceType.EVIDENCE.getType(),
				ScEventType.CREATEWAREHOUSERECEIPT.getType(), UserUtils.getUser().getId());
		scEventMapper.insertScEvent(scEvent2);

		return evidenceId;
	}

	/**
	 * 保存采购单不GV
	 *
	 * @param purchaseOrderJson
	 */
	@Transactional(readOnly = false)
	public void savePurchaseOrder(JSONObject purchaseOrderJson) {
		try {
			// 如果是生成入库单 执行此方法
			String createWarehouse = purchaseOrderJson.getString("createWarehouse");
			if (null != createWarehouse && createWarehouse.equals("createWarehouse")) {

				this.createWarehouseReceipt(purchaseOrderJson.getString("purchaseOrderId"), true);
			}

			// 校验参数
			String purchaseOrderId = purchaseOrderJson.getString("purchaseOrderId");
			User logUser = UserUtils.getUser();
			if (null != purchaseOrderId) {
				PurchaseOrderItem purchaseOrderItem = new PurchaseOrderItem();
				purchaseOrderItem.setPurchaseOrderId(purchaseOrderId);
				List<PurchaseOrderItem> itemList = purchaseOrderItemService.findList(purchaseOrderItem);
				purchaseOrderItemService.deleteAll(itemList);
				purchaseOrderMapper.updateRemarks(purchaseOrderJson.getString("remarks"), purchaseOrderId);
			} else {
				// 保存合同主表信息
				SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
				PurchaseOrder purchaseOrder = new PurchaseOrder();
				purchaseOrder.setContractId(purchaseOrderJson.getString("contractId"));
				purchaseOrder.setSupplierId(purchaseOrderJson.getString("supplierId"));
				purchaseOrder.setState(EvidenceLockState.UNLOCK.getValue());
				purchaseOrder.setDeliveryDate(purchaseOrderJson.getString("deliveryDate"));
				purchaseOrder.setIsTax(purchaseOrderJson.getString("isTax"));
				purchaseOrder.setTax(purchaseOrderJson.getString("tax"));
				purchaseOrder.setInvoiceType(purchaseOrderJson.getString("invoiceType"));
				purchaseOrder.setRemarks(purchaseOrderJson.getString("remarks"));

				if (purchaseOrderJson.getString("purchaseDate") == null) {
					purchaseOrder.setPurchaseDate(new Date());
				} else {
					purchaseOrder.setPurchaseDate(sdf.parse(purchaseOrderJson.getString("purchaseDate")));
				}

				super.save(purchaseOrder);

				purchaseOrderId = purchaseOrder.getId();
			}

			JSONArray items = (JSONArray) purchaseOrderJson.get("items");
			if (null == items) {
				return;
			}
			PurchaseOrderItem orderItem;
			JSONObject objectItem;
			for (int i = 0; i < items.size(); i++) {
				objectItem = (JSONObject) items.get(i);
				orderItem = new PurchaseOrderItem();
				orderItem.setSkuId(objectItem.getString("skuId"));
				orderItem.setNum(objectItem.getInteger("num"));
				orderItem.setPrice(objectItem.getBigDecimal("price"));
				orderItem.setPurchaseOrderId(purchaseOrderId);
				orderItem.setCreateDate(new Date());
				orderItem.setCreateBy(logUser);
				purchaseOrderItemService.save(orderItem);
			}

			// 保存采购单动作
			ScEvent scEvent = new ScEvent(purchaseOrderId, ScEventServiceType.PURCHASEORDER.getType(),
					ScEventType.CREATEPURCHASEORDER.getType(), UserUtils.getUser().getId());
			scEventMapper.insertScEvent(scEvent);
		} catch (Exception e) {
			// 打印当前堆栈异常信息
			logger.error("service Error PurchaseOrderService -> savePurchaseOrder   " + e.fillInStackTrace());
		}
	}

	/**
	 * 
	 * 保存采购单并且创建入库单
	 * 
	 * @param purchaseOrderJson
	 * @author: Fyh - 1009173473@qq.com 
	 * @throws Throwable 
	 * @date: Created on 2019年4月8日 下午4:36:32
	 */
	@Transactional(readOnly = false)
	public WarehouseReceipt savePurchaseOrderAndCreateWareReceipt(JSONObject purchaseOrderJson) throws Throwable {
		// step1 创建采购单
		User logUser = UserUtils.getUser();
		// 采购主表信息
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		PurchaseOrder purchaseOrder = new PurchaseOrder();
		purchaseOrder.setContractId(purchaseOrderJson.getString("contractId"));
		purchaseOrder.setSupplierId(purchaseOrderJson.getString("supplierId"));
		purchaseOrder.setState(EvidenceLockState.UNLOCK.getValue());
		purchaseOrder.setDeliveryDate(purchaseOrderJson.getString("deliveryDate"));
		purchaseOrder.setIsTax(purchaseOrderJson.getString("isTax"));
		purchaseOrder.setTax(purchaseOrderJson.getString("tax"));
		purchaseOrder.setInvoiceType(purchaseOrderJson.getString("invoiceType"));
		purchaseOrder.setRemarks(purchaseOrderJson.getString("remarks"));
		if (purchaseOrderJson.getString("purchaseDate") == null) {
			purchaseOrder.setPurchaseDate(new Date());
		} else {
			purchaseOrder.setPurchaseDate(sdf.parse(purchaseOrderJson.getString("purchaseDate")));
		}
		// 保存采购主表
		super.save(purchaseOrder);

		// 返回采购id
		String purchaseOrderId = purchaseOrder.getId();

		// 采购植物详情
		JSONArray items = (JSONArray) purchaseOrderJson.get("items");
		if (null == items) {
			return null;
		}
		PurchaseOrderItem orderItem;
		JSONObject objectItem;
		for (int i = 0; i < items.size(); i++) {
			objectItem = (JSONObject) items.get(i);
			orderItem = new PurchaseOrderItem();
			orderItem.setSkuId(objectItem.getString("skuId"));
			orderItem.setNum(objectItem.getInteger("num"));
			orderItem.setPrice(objectItem.getBigDecimal("price"));
			orderItem.setPurchaseOrderId(purchaseOrderId);
			orderItem.setCreateDate(new Date());
			orderItem.setCreateBy(logUser);
			purchaseOrderItemService.save(orderItem);
		}

		// step2 创建入库单
		WarehouseReceipt warehouseReceipt = new WarehouseReceipt();
		warehouseReceipt.setReceiptType(EvidenceType.PURCHASERECEIPT.getType());
		String evidenceId = warehousingFacade.createWarehouseReceipt(warehouseReceipt);
		warehouseReceipt.setEvidenceId(evidenceId);
		warehouseReceipt.setJsons(purchaseOrderJson.get("items").toString());
		// 更新采购单
		purchaseOrder.setState(EvidenceLockState.LOCK.getValue());
		purchaseOrder.setEvidenceId(evidenceId);
		this.save(purchaseOrder);

		return warehouseReceipt;
	}

	public List<PurchaseOrderItemErpInfo> findErpInfoBySkuId(String skuId, String companyId) {
		return mapper.findErpInfoBySkuId(skuId, companyId);
	}

}